Skip to content

feat(sdk): integrate Pierre stack and Inspect for 0.7.1 - #362

Merged
ebursztein merged 87 commits into
0.7from
integration/0.7.1-pierre-sdk-20261016
Oct 19, 2026
Merged

ebursztein merged 87 commits into
0.7from
integration/0.7.1-pierre-sdk-20261016

Conversation

@ebursztein

@ebursztein ebursztein commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

The SDKs discover and authenticate to the running local gateway without URL, IP or key arguments (#344). Explicit remote connections require a complete credential pair; discovery metadata remains bounded, private and opened without following symlinks.

This branch includes Pierre's full #336–#340 stack: VM labels, typed errors, gateway discovery and the SDK-backed Inspect adapter for VM, OCI, Compose and authorized host builds. It preserves service-managed sessions, supervised worker identity, authenticated IPC and logger ownership.

Current exact source: 6b77f42b97514a3fc0b03e57407c47b3f59e46d2. It includes corrected native 0.7 source f6c785a0d1b9297e7a4826a16dd3716a775c9f03 and all five current Pierre heads. Required CI: https://github.com/google/capsem/actions/runs/39280019460. This draft remains based on 0.7 while #359 ships. Final complete local patch qualification is pending.

Stable native publication hands qualified archives to the registry continuation. It validates source, versions and dependencies, publishes dependencies first, rejects immutable byte conflicts, verifies anonymous downloads and runs clean external consumers against the matching native service. Native and SDK/MCP versions are 0.7.1; Inspect is 0.1.0 and requires capsem>=0.7.1. Verification builds receive no publishing tokens.

The public installer verifier uses the qualified systemd helper, proves clean-image ownership, runs installation as the ordinary user and removes its unique container on exit or interruption. Source-contract collection preserves prefix siblings for unslashed roots. CLI approval retains annotated nested fields and rejects unparsed marked fields. The host-ledger doctor reports invalid binary fields as corruption while preserving the Rust hash format.

Focused review fixes pass four collection, 16 public-surface and 20 ledger tests, including real SQLite corruption through the actual doctor verifier, plus Ruff, canonical strict Ty and 25 shape/type-debt guards. Earlier component evidence includes 528 Python SDK tests, 1125 TypeScript SDK tests, 107 Inspect tests with real BuildKit/isolated packaging, packaged-client discovery against a native service and five Cargo archives. Component results do not replace final whole-source qualification.

Release holds: final local proof, required CI, npm/Cargo publisher authority, Inspect PyPI token scope and actual public installation. Team ownership of PyPI capsem is confirmed and PYPI_TOKEN is present. No 0.7.1 tag or publication is claimed. Physical Mac/Tart/VZ is explicitly deferred; hosted signing, notarization and native installation remain required. Unsupported official native AGY sign-in remains an explicit limit in #359.

tholop and others added 21 commits October 14, 2026 08:46
Add `AppError::new(status, error)` and mechanically rewrite tuple-struct
call sites across `crates/capsem-service/src` so subsequent structured
error fields and helper constructors do not mix with mechanical renames.

Generated with:

    python3 -c 'import pathlib, re; [p.write_text(re.sub(r"\bAppError\((?!pub\b|status\b)", "AppError::new(", p.read_text())) for p in pathlib.Path("crates/capsem-service/src").rglob("*.rs")]' && cargo fmt -p capsem-service
…ck OCI registry

Add evaluator-granted host-side Dockerfile and Compose `build:` image building
and a read-only loopback HTTPS OCI v2 registry to `inspect-capsem-sandbox`:

- Add `HostBuildGrant` (`containers/build_grant.py`) enforcing evaluator
  environment authority (`CAPSEM_INSPECT_HOST_BUILD=1`,
  `CAPSEM_INSPECT_ALLOWED_HOST_PATHS`, `CAPSEM_INSPECT_BUILD_NETWORK`,
  `CAPSEM_INSPECT_BUILD_DOCKER_CONFIG`) with task-level narrowing and strict
  refusal of `--network host`.
- Add `containers/build_context.py` for canonical path containment, symlink
  escape rejection, `.dockerignore` context tree walking, deterministic cache
  key hashing, and unified Compose `build:` / `dockerfile:` normalization.
- Add `containers/image_build.py`, `containers/oci_ingest.py`, and
  `containers/oci_registry.py` to build OCI archives via `docker build` /
  `buildx`, ingest OCI-layout and legacy `docker-save` tars into a content-
  addressed blob store (skipping BuildKit attestation manifests), and serve
  verified digests over a loopback TLS 1.2+ `/v2/` registry with 0.7 `[images]`
  `sources`, `ca_pem`, and `admit` profile wiring.
Add structured `ErrorResponse` fields (`code: ErrorCode`, `vm_id`,
`timeout_secs`) on the HTTP wire contract, return HTTP 504
(`GATEWAY_TIMEOUT`) on service-side exec and container create timeouts,
and expose structured Python SDK exceptions (`CapsemError`,
`CapsemTimeoutError`, `CreateTimeoutError`, `ExecTimeoutError`,
`VmNotFoundError`) plus `MAX_REQUEST_BODY_BYTES` and `CREATE_READY_SECS`
in the Python and TypeScript SDKs.
Stage .capsem-ca.crt and .capsem-ca-bundle.crt into a temporary build
context when CAPSEM_INSPECT_BUILD_CA_PEM_FILE (and optional
CAPSEM_INSPECT_BUILD_CA_BUNDLE_FILE) is set, seed NSS sql:$HOME/.pki/nssdb
via certutil during builds and container startup, require BuildKit on the
host (removing the legacy 0.6 classic-builder heredoc lowering module), and
include the CA fingerprint in build cache keys.
…list

Allow callers to attach optional key/value string labels to VMs at
creation time, inherit or override them on fork, and return them on
every SandboxInfo entry in /vms/list and /vms/{id}/info so external
orchestrators and garbage collectors can identify their own VMs.

- capsem-api / capsem-service / OpenAPI: add optional labels
  (Option<HashMap<String, String>>) to ProvisionRequest, ForkRequest,
  SandboxInfo, VmInstance, SessionCreationParams, and PersistentVmEntry,
  validated server-side via naming::validate_vm_labels (<= 64 entries,
  keys reuse validate_vm_name: 1..=64 ASCII chars starting with
  [A-Za-z0-9] and containing only [A-Za-z0-9_-]; values <= 255 UTF-8
  bytes with no control chars) and normalized via
  naming::non_empty_labels so {} is treated identically to None.
- Fork inheritance: /vms/{id}/fork inherits the source VM's labels when
  ForkRequest.labels is omitted/null, replaces them when a non-empty map
  is provided, and clears them when {} is provided.
- List cache fingerprint: include running and inactive VM labels in
  list_response_fingerprint via append_labels_fingerprint so label
  differences invalidate cached /vms/list responses.
- SDKs (Python, Rust, TypeScript): thread optional labels through
  Hypervisor.create / CreateOptions and VM.fork / ForkOptions and
  regenerate OpenAPI models across all three SDKs.
- CLI & TUI: add repeatable -l / --label KEY=VALUE to capsem create and
  capsem fork, and display labels in the TUI session detail pane.
- Service test helpers & Citadel ratchets: consolidate ProvisionOptions
  and PersistentVmEntry test constructors via test_provision_options and
  test_persistent_entry in crates/capsem-service/src/tests.rs (reducing
  tests/lifecycle.rs and tests/assets_registry.rs by ~100 lines) and
  update the four corresponding oversized-Rust-file line ratchets in
  config/gate.toml.
Add `discover_gateway`, `capsem_run_dir`, `GatewayEndpoint`,
`Hypervisor.connect`, and optional `url`/`token`/`run_dir` parameters on
`Hypervisor` and `VM` resolving `CAPSEM_GATEWAY_URL`,
`CAPSEM_GATEWAY_TOKEN`, and `<run_dir>/gateway.{port,token}`.
…ration

Port the inspect-capsem Inspect AI SandboxEnvironment integration onto
the 0.7 Python SDK surface in VM-only mode (container/image execution
deferred to the follow-up container commit):

- Split the implementation across focused modules under
  integrations/inspect-ai/inspect_capsem/ (config.py, _cleanup.py,
  _controller.py, _exec.py, _files.py, _lifecycle.py, _registry.py,
  _tools.py, _transfer.py, sandbox.py) with every module under 300 lines
  at 100 columns.
- Encapsulate private CapsemSandboxEnvironment state inside sandbox.py,
  return SandboxConnection(type="capsem", command="capsem shell <id>"),
  and bound process-owned VM teardown at interpreter exit.
- Derive staged file transfer part sizes from MAX_REQUEST_BODY_BYTES,
  scope VM cleanup to exact managed-by + prefix labels, and clean up
  unnamed VMs on 504 CreateTimeoutError via CreateTimeoutError.vm_id.
- Harden non-root user environment reset when id -un prints numeric UID
  to stdout and exits 1 or pwd.getpwuid raises KeyError in minimal
  containers.
- Wire integrations/inspect-ai into capsem-gate, CI scope routing,
  installed wheel/sdist entry-point proof (image_package_acceptance.py),
  and live VM ironbank acceptance (live_acceptance.py + test_sdk_live.py).

Proves #310 / #342 acceptance criteria:
- [x] `inspect_capsem` registers cleanly as an `inspect_ai`
  `SandboxEnvironment` entry point (`@sandboxenv(name="capsem")`) from
  an installed `inspect-capsem-sandbox` wheel and sdist in an isolated
  prefix (`integrations/inspect-ai/tests/image_package_acceptance.py`).
- [x] `sample_init`, `exec` (`ExecTarget.VM` with non-zero exit, signal,
  and timeout), `read_file`/`write_file` (text, binary, non-workspace),
  Inspect's `self_check` suite, `eval_async` with `SandboxEnvironmentSpec("capsem", ...)`,
  `sample_cleanup`, `task_cleanup`, and prefix-scoped `cli_cleanup` run
  against the live service with session ledger (`history(layer=EXEC)` +
  `session.db` `exec_events`) and zero leaked VMs.
Add OCI container execution mode (`execution_mode="container"`, `image=...`,
and `compose.yaml` / `docker-compose.yml` config parsing) on top of Capsem VM
sandboxes:

- `inspect_capsem/containers/compose.py` + `compose_fields.py` + `compose_inputs.py` + `compose_interpolation.py` + `compose_service.py` + `compose_values.py`: single bounded Compose parser built on `ComposeInputs`, `ComposeLimits` / `_BoundedSafeLoader`, and `InterpolationBudget` with redacted diagnostics, default-deny host environment interpolation (`SAMPLE_METADATA_*` allowlist with `.env` spoofing rejection), support for `image`, `command`/`entrypoint`, `environment`, `working_dir`, `user`, `volumes` (read-write and `:ro` bind mounts with symlink and project-root containment), `healthcheck`, `cpus`/`mem_limit`, and fail-closed validation on unsupported service keys, network isolation overrides, and multi-service topologies.
- `inspect_capsem/containers/runtime.py` + `controller.py`: OCI container staging (`prepare_oci_workload_container`, `_stage_oci_bind_volumes`) and `ContainerController` protocol.
- `inspect_capsem/_compose.py`, `_controller.py`, `_exec.py`, `_files.py`, `_lifecycle.py`, `config.py`, `sandbox.py`: thread container execution mode, non-root `user` execution (`su -m` / `setpriv`, skipping privilege switching when already running at target UID/GID inside non-root workloads and raising `PermissionError` when requesting a root or different user switch inside a `no-new-privileges` non-root workload), `/workspace` staging, and `SdkCapsemController` `registry_ca_pem` / `Registry(ca_pem=...)` plumbing (moved from PR #340 into PR #339 so #339's hermetic loopback TLS OCI workload fixture authenticates without #340 while `CapsemSandboxConfig` continues to reject `registry_ca_pem` in untrusted task configs).
- Unit tests (`tests/containers/*`, `tests/test_config.py`, `tests/test_sandbox*.py`) and hermetic loopback TLS OCI workload acceptance (`tests/oci_workload_fixture.py`, `tests/live_acceptance.py`).

Proves #310 / #311 / #342 acceptance criteria:
- [x] Compose config coercion (`compose.yaml` / `docker-compose.yml`) and `CapsemSandboxConfig(image=...)` select `execution_mode="container"` and route `exec` to `ExecTarget.WORKLOAD`.
- [x] Hermetic OCI workload acceptance (`tests/oci_workload_fixture.py` + `tests/live_acceptance.py`) builds a digest-pinned OCI image from the guest initrd busybox, serves it over loopback TLS with a per-run CA passed via `SdkCapsemController(registry_ca_pem=...)`, admits its digest in `settings.toml`, runs `sample_init`, `exec` (`ExecTarget.WORKLOAD`), `write_file`/`read_file` (text and binary), and `eval_async` with `SandboxEnvironmentSpec("capsem", ...)` without pulling from Docker Hub, and verifies `history(layer=EXEC)` + `session.db` `exec_events` (`target="workload"`) and zero leaked VMs after `sample_cleanup`.
Extend `run_live_vm_sandbox_acceptance` (invoked by the live VM gate
`test_inspect_ai_live_vm_sandbox_acceptance`) with
`verify_host_build_workload_mode` (`#342` bullets 2, 5, and 6):

- Require the `docker` CLI and daemon on `PATH` and fail loudly if
  absent (no silent skip; `#342` bullet 5).
- Load a hermetic busybox base image from the guest initrd into local
  Docker and build a multi-stage `Dockerfile` + `compose.yaml` (`build:`
  with `context`, `dockerfile`, `target`, and `args`) completely offline
  (`CAPSEM_INSPECT_BUILD_NETWORK=none`).
- Verify fail-closed refusals when `CAPSEM_INSPECT_HOST_BUILD` is unset,
  when a symlink escapes the build context, and when `HostBuildGrant`
  attempts to widen `allowed_contexts` or `network` beyond the operator
  environment ceiling.
- Verify multi-stage `FROM ... AS ...`, `FROM scratch`, `ARG`/`ENV`,
  `WORKDIR`, `USER 1000:1000`, `ENTRYPOINT`/`CMD`, `COPY --from` with
  `--chown`/`--chmod`, heredoc `RUN`/`COPY`, `ADD` local tar extraction,
  `.dockerignore` exclusion, real `inspect-sandbox-tools` host binary
  upload (`700:1000:1000`) and onedir archive extraction as UID
  `1000:1000` (`RUN rm -rf /var/tmp/sandbox-services` before
  `USER 1000:1000`), and `CAPSEM_INSPECT_BUILD_CA_PEM_FILE` CA injection
  (including byte-for-byte PEM equality inside the live guest container)
  on a real VM workload container (`#342` bullets 2 and 6).
- Verify non-root `USER 1000:1000` container file round-trip (`write_file`,
  in-container append, `read_file`), `PermissionError` on `user="root"`
  privilege escalation under `no-new-privileges`, and `inspect_ai`'s
  portable `self_check` suite against the `USER 1000:1000` container.
- Pin a stable loopback OCI registry port (preferring default `5055` via
  `CAPSEM_INSPECT_BUILD_REGISTRY_PORT` and falling back to an available
  loopback port if `5055` is busy) across `settings.toml` `[images]`
  source admission and verify second-sample digest cache reuse without a
  second `docker build` even after tightening `settings.toml` to
  digest-only admission.
- Load sibling test modules in standalone `python -I` gateway consumer
  runs via `importlib.util.spec_from_file_location` without mutating
  `sys.modules["tests"]`, and use `unittest.mock.patch.object` for test
  seam overrides.
@codecov-commenter

codecov-commenter commented Oct 16, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.33959% with 724 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.4%. Comparing base (f6c785a) to head (e67dc1c).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...m/builder/release/tools/client_package_archives.py 0.0% 110 Missing ⚠️
..._system/builder/release/tools/client_publishers.py 0.0% 103 Missing ⚠️
...ld_system/builder/release/tools/client_registry.py 0.0% 69 Missing ⚠️
...d_system/builder/release/tools/client_consumers.py 0.0% 54 Missing ⚠️
...d_system/builder/release/tools/package_rust_sdk.py 0.0% 52 Missing ⚠️
...stem/builder/release/tools/public_install_smoke.py 55.1% 26 Missing ⚠️
crates/capsem-service/src/vm_lifecycle.rs 35.8% 20 Missing and 5 partials ⚠️
...ns/inspect-ai/inspect_capsem/containers/runtime.py 84.1% 10 Missing and 10 partials ⚠️
...inspect-ai/inspect_capsem/containers/oci_ingest.py 87.4% 7 Missing and 9 partials ⚠️
crates/capsem-api/src/files.rs 36.3% 14 Missing ⚠️
... and 60 more
Additional details and impacted files
@@            Coverage Diff             @@
##              0.7     #362      +/-   ##
==========================================
- Coverage    74.9%    69.4%    -5.6%     
==========================================
  Files        1382     1880     +498     
  Lines      114630   154368   +39738     
  Branches   109528   114303    +4775     
==========================================
+ Hits        85962   107137   +21175     
- Misses      22241    40367   +18126     
- Partials     6427     6864     +437     
Flag Coverage Δ
inspect-ai 93.6% <95.2%> (?)
integration 19.5% <ø> (+<0.1%) ⬆️
linux-unit 74.1% <66.6%> (+0.7%) ⬆️
mcp-server 94.9% <ø> (+<0.1%) ⬆️
python-sdk 98.1% <ø> (+<0.1%) ⬆️
typescript-sdk 97.0% <ø> (+<0.1%) ⬆️
unit 67.4% <77.3%> (+41.7%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
TypeScript SDK 97.0% <ø> (+<0.1%) ⬆️
Python SDK 98.1% <ø> (+<0.1%) ⬆️
Inspect AI Extension 93.6% <95.2%> (∅)
Network 85.0% <ø> (+<0.1%) ⬆️
Security 83.6% <ø> (ø)
Tooling 89.5% <ø> (ø)
Monitoring 86.4% <ø> (+0.3%) ⬆️
Virtualization 69.9% <ø> (+0.3%) ⬆️
Confined Port Router 76.3% <ø> (-0.3%) ⬇️
Private Network 77.6% <ø> (+6.5%) ⬆️
Assets 81.8% <ø> (ø)
Gateway API 94.8% <39.1%> (-1.8%) ⬇️
Rust SDK 95.3% <ø> (+<0.1%) ⬆️
Configuration 88.3% <ø> (ø)
Credentials 84.4% <ø> (ø)
Host Foundation 77.1% <ø> (-0.4%) ⬇️
Cache 92.4% <ø> (∅)
Cryptography 91.6% <ø> (∅)
Core Platform 55.8% <ø> (ø)
Runtime 69.1% <ø> (+<0.1%) ⬆️
Daemon 41.6% <ø> (∅)
Service 75.5% <67.6%> (+4.5%) ⬆️
Process 47.8% <ø> (-0.7%) ⬇️
Proxy 43.6% <ø> (+<0.1%) ⬆️
Ledger 63.0% <ø> (ø)
Admin 70.3% <ø> (+0.7%) ⬆️
CLI 49.0% <73.9%> (-0.6%) ⬇️
MCP Server 94.9% <ø> (+<0.1%) ⬆️
MCP Transport 62.1% <ø> (∅)
MCP Aggregator 66.2% <ø> (ø)
MCP Builtin 63.1% <ø> (ø)
Gateway 76.5% <ø> (-0.8%) ⬇️
TUI 68.8% <0.0%> (ø)
System Tray 56.2% <ø> (∅)
Guard 92.2% <ø> (ø)
UI 83.4% <ø> (∅)
Release Site 25.6% <ø> (ø)
Builder 42.1% <17.2%> (∅)
Mock Server 71.5% <ø> (ø)
Bench 54.5% <ø> (+0.8%) ⬆️
Files with missing lines Coverage Δ
build_system/builder/gate/buildschema.py 97.2% <100.0%> (ø)
build_system/builder/gate/config.py 91.0% <100.0%> (ø)
build_system/builder/gate/configschema.py 95.0% <100.0%> (ø)
build_system/builder/gate/pytestsuite.py 97.8% <100.0%> (ø)
build_system/builder/gate/sdkchecks.py 100.0% <100.0%> (ø)
build_system/builder/gate/sdkregistrychecks.py 100.0% <100.0%> (ø)
build_system/builder/gate/testmodules.py 97.0% <100.0%> (ø)
crates/capsem-api/src/lifecycle.rs 91.4% <100.0%> (+<0.1%) ⬆️
crates/capsem-service/src/connection_routes.rs 60.7% <100.0%> (ø)
crates/capsem-service/src/errors.rs 92.8% <100.0%> (+12.8%) ⬆️
... and 130 more

... and 504 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Hosted Linux x86 coverage in CI38935897735 failed the existing already-exited-shell test at633ms against its500ms wall-clock assertion. A100ms setup sleep did not prove the child exited; shared-host scheduling is outside the shutdown contract. Observe the real unreaped exit with the existing foundation primitive, prove success with zero grace and positive reaping, and synchronize ignored-HUP readiness over stdout. Production shutdown behavior is unchanged. Focused nine shutdown tests, formatting and changed-owner Clippy pass.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for advisory metadata labels on sandboxes across the service, API, and all SDKs (Python, TypeScript, and Rust), enabling better tracking and categorization of VMs. It also refactors error handling by introducing a structured ErrorCode enum and adding metadata fields (vm_id, timeout_secs) to ErrorResponse and AppError to provide more diagnostic context on failures. Additionally, it fully implements the standalone inspect-capsem-sandbox (inspect_capsem) integration for Inspect AI, supporting both VM and container/Compose execution modes, host-side OCI image builds with CA patching, and local registry hosting. The build system and gate have been updated to run standalone lint, type, test, and build checks for this new integration. I have no feedback to provide as there are no review comments.

Stamp the user-selected0.7.1 version across native, Rust library publication constraints, Python, Node, MCP and builder metadata; require capsem>=0.7.1 for Inspect labels and typed-error APIs. Refresh Cargo/uv/pnpm locks with their owners. Review confirms32first-party Cargo version changes and no upstream Cargo/Python dependency version drift. Correct the stale Inspect editable SDK lock0.6.3 and add a source guard with four adversarial cases; genuineRED before refresh,48focused version/contracts,4lock/type checks and47shape/web guards pass. Document the matching service prerequisite and complete-pair credential discovery, replacing retired parser-only/legacy-heredoc notes.
Install job117096865747 source-built the pinned Cargo tools from17:12 through17:30, then downloaded those same versions as prebuilts in six seconds. Move the existing declared-tool selection and pinned install action before the complete bootstrap so its exact-version probes can reuse them. Keep full QEMU/binfmt/device provisioning and asset ownership. Genuine ordering guard RED before reorder; fifteen prerequisite and adversarial tests, Ruff and canonical source syntax pass. Hosted after-times remain unmeasured; primary0.7 candidate stays frozen.
CI38960767456 fast.citadel caught the new cohort guard reading bare project manifest and lock names. Use the declared Inspect manifest and audit lock inventory instead of adding obsolete-path debt. Existing guard reproduced RED;36 focused SDK/path checks and configured Ruff pass.
CI38960767456 packed-package workflow and the focused local tarball test exposed the literal0.7.0 after the0.7.1 version update. Read the installed package manifest once with a module-relative createRequire. Production build and actual isolated authenticated tarball workflow pass; no test expectation or protocol name changes.
Preserve Inspect PythonPackageConfig and add the specialized TypeScript SDK configuration. Focused merged-source schema/deadline/shape checks pass27 tests; strict type checking and lint pass. Native hosted failures117308250318 and117308264535 are diagnosed in the merged fix; no unchanged CI retry.
The optional public Docker verifier ran bash as PID1 in plain Ubuntu,
then asserted that an installed systemd service and gateway were healthy.
Keep the installer path, but boot its prepared systemd image and ordinary
user before executing the public installer.

Share the boot primitive with both existing sealed install owners. Keep
their network=none contract and readiness budgets intact; only the public
download proof explicitly uses bridge. Require a clean prepared image,
reuse the configured package inventory, own a unique container, and
remove it on failure or SIGTERM while restoring the previous handler.

The boot regression failed on the original verifier. SIGTERM cleanup was
also RED before the handler. Focused checks:53 public/container tests,
55 shared-owner tests,24 staged shape guards, Ruff, strict source Ty,
targeted test Ty and the exact type-debt guard pass. A real pinned-helper
probe confirmed systemd PID1, the ordinary user manager and an active
user unit, then removed the container.

Actual public installer execution remains a post-publication proof.
Native0.7 source489c is untouched and continues its final qualification.
Keep mocked release contracts portable to hosts without Docker. The Dockerless reproduction fails twice before the fixture and passes both tests after it; Ruff and the unchanged Python type-debt guard pass.
The complete release contract run found one stale assertion after the public installation helper extraction. Inspect the actual routed smoke function source file, preserving the updater assertion. Focused public installer contracts: 21 passed; shape and unchanged type-debt guards: 28 passed; Ruff passed.
Register the extracted public installer helper as release support and classify its new unit tests explicitly. Preserve exact namespace and test-ownership enforcement. Both original guards reproduced RED; all 16 related ownership/tool/installer tests pass, along with 27 shape checks and Ruff.
Use component-aware containment when selecting external collection paths. Current configured roots already end in slashes; valid unslashed roots must also retain similarly named sibling paths. Regression: one failed/one passed before, all four focused collection checks pass after. Ruff, canonical strict Ty, and25 shape/type-debt guards pass. Native09c qualification remains on its frozen tree; final patch qualification is pending.
Recognize comments and attributes between the subcommand marker and its own field, including bracket/comma-containing attribute strings. Reject marked fields that cannot be parsed; never scan into another field or silently shrink the approved command inventory. Seven focused regressions failed before; all16 public-surface tests pass, including the actual unchanged allowlist. Ruff, canonical strict Ty and25 shape/type-debt guards pass. Final patch qualification remains required.
Reject text, null, integer and list values for detail and chain hashes with ValueError so the existing doctor error boundary records corruption. Preserve the Rust BLOB contract and exact hash format, including valid bytes, bytearray and memoryview. Fifteen regressions failed before; all20 ledger tests pass after, including real SQLite TEXT corruption through the actual doctor verifier and the Rust golden vector. Ruff, canonical strict Ty and25 shape/type-debt guards pass. Final patch qualification remains pending.
@ebursztein
ebursztein marked this pull request as ready for review October 19, 2026 23:35
@ebursztein
ebursztein merged commit 60373af into 0.7 Oct 19, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants